package com.sc.admin.service.impl;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.sc.admin.common.constant.CacheConstant;
import com.sc.admin.common.exception.BusinessException;
import com.sc.admin.common.result.ResultCodeEnum;
import com.sc.admin.common.util.CacheUtils;
import com.sc.admin.common.util.ObjUtils;
import com.sc.admin.common.util.PasswordEncoderUtils;
import com.sc.admin.model.dto.LoginResult;
import com.sc.admin.model.dto.UserAuthInfo;
import com.sc.admin.service.AuthService;
import com.sc.admin.service.SysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * 认证服务实现类
 *
 * @author haoxr
 * @since 2.4.0
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AuthServiceImpl implements AuthService {

    private final SysUserService sysUserService;

    /**
     * 登录
     *
     * @param username 用户名
     * @param password 密码
     * @return 登录结果
     */
    @Override
    public LoginResult login(String username, String password) {
        UserAuthInfo userAuthInfo = sysUserService.getUserAuthInfo(username);
        if (userAuthInfo == null) {
            throw new BusinessException(ResultCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        //  比较密码
        if (ObjUtils.notEquals(PasswordEncoderUtils.encode(password), userAuthInfo.getPassword())) {
            throw new BusinessException(ResultCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        // 把用户信息放入缓存 这样可以在 登录的监听中获取到用户的信息
        // 注意: 只有在重新登录的时候会刷新缓存的数据, 其他情况都不刷新
        CacheUtils.set(CacheConstant.USER_INFO + userAuthInfo.getUserId(), userAuthInfo);

        // 第1步，先登录上
        StpUtil.login(userAuthInfo.getUserId());
        // 第2步，获取 Token  相关参数
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        return LoginResult.builder()
                .tokenType("Bearer")
                .accessToken(tokenInfo.getTokenValue())
                .build();
    }

    /**
     * 注销
     */
    @Override
    public void logout() {
        Object loginId = StpUtil.getLoginId();
        StpUtil.logout();
        CacheUtils.delete(CacheConstant.USER_INFO + loginId);
    }
}
